package com.plug.common.jdbc;

import com.plug.entity.PlugDatasource;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Created by slaye on 2016/12/16.
 */
public class DBConnectionPool {
    private Connection con = null;
    private int inUsed = 0; // 使用的连接数
    private ArrayList freeConnections = new ArrayList();// 容器，空闲连接
    private int minConn; // 最小连接数
    private int maxConn; // 最大连接
    private String name; // 连接池名字
    private String password; // 密码
    private String url; // 数据库连接地址
    private String driver; // 驱动
    private String user; // 用户名


    /**
     *
     *@类名：DBConnectionPool.java
     *@描述：{构造函数}
     */
    public DBConnectionPool() {
        //do nothing
    }

    public static void main(String[] args) {
    }

    /**
     *
     *@类名：DBConnectionPool.java
     *@描述：{根据数据库的信息，构造连接池}
     * @param name 连接池名称
     * @param driver 数据库驱动
     * @param URL   地址
     * @param user  用户名
     * @param password 密码
     * @param maxConn 最大连接数
     */
    public DBConnectionPool(String name, String driver, String URL, String user, String password, int maxConn) {
        this.name = name;
        this.driver = driver;
        this.url = URL;
        this.user = user;
        this.password = password;
        this.maxConn = maxConn;
    }


    /**
     *
     * 函数功能说明:释放连接
     * @param con 连接对象
     * @return void
     * @throws
     */
    public synchronized void freeConnection(Connection con) {
        this.freeConnections.add(con);// 添加到空闲连接的末尾
        this.inUsed--;
    }

    /**
     *
     * 函数功能说明:获取一个没有使用的连接
     * @return Connection 连接对象
     * @throws
     */
    public synchronized Connection getConnection() {
        Connection con = null;
        if (this.freeConnections.size() > 0) {
            con = (Connection) this.freeConnections.get(0);
            this.freeConnections.remove(0);// 如果连接分配出去了，就从空闲连接里删除
            if (con == null) {
                con = getConnection(); // 继续获得连接
            }
        } else {
            if (this.maxConn == 0 || this.maxConn < this.inUsed) {
                con = null;// 等待 超过最大连接时
            } else {
                con = newConnection(); // 新建连接
            }
        }
        if (con != null) {
            this.inUsed++;
//            System.out.println("得到　" + this.name + "　的连接，现有" + inUsed + "个连接在使用!");
        }
        return con;
    }


    /**
     *
     * 函数功能说明:释放连接池的全部链接
     * @return void
     * @throws
     */
    public synchronized void release() {
        Iterator allConns = this.freeConnections.iterator();
        while (allConns.hasNext()) {
            Connection con = (Connection) allConns.next();
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }
        this.freeConnections.clear();

    }

    /**
     *
     * 函数功能说明:创建一个新的连接
      * @return Connection 连接对象
     * @throws
     */
    private Connection newConnection() {
        try {
            Class.forName(driver);
            con = DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("sorry can't find db driver!");
        } catch (SQLException e1) {
            e1.printStackTrace();
            System.out.println("sorry can't create Connection!");
        }
        return con;

    }

    /**
     * 获取JDBCInfoBean
     * @param plugDatasource
     */
    public static JDBCInfoBean createJDBCInfoBean(PlugDatasource plugDatasource) {
        JDBCInfoBean jdbcInfoBean = new JDBCInfoBean();
        jdbcInfoBean.setName(plugDatasource.getDsName());
        jdbcInfoBean.setDriver(plugDatasource.getDsDriver());
        jdbcInfoBean.setPassword(plugDatasource.getDsPassword());
        jdbcInfoBean.setUrl(plugDatasource.getDsUrl());
        jdbcInfoBean.setUsername(plugDatasource.getDsUsername());
        return jdbcInfoBean;
    }


    /**
     * @return the driver
     */
    public String getDriver() {
        return driver;
    }

    /**
     * @param driver
     *  the driver to set
     */
    public void setDriver(String driver) {
        this.driver = driver;
    }

    /**
     * @return the maxConn
     */
    public int getMaxConn() {
        return maxConn;
    }

    /**
     * @param maxConn
     *  the maxConn to set
     */
    public void setMaxConn(int maxConn) {
        this.maxConn = maxConn;
    }

    /**
     * @return the minConn
     */
    public int getMinConn() {
        return minConn;
    }

    /**
     * @param minConn
     *  the minConn to set
     */
    public void setMinConn(int minConn) {
        this.minConn = minConn;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *  the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param password
     *  the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * @return the url
     */
    public String getUrl() {
        return url;
    }

    /**
     * @param url
     *  the url to set
     */
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * @return the user
     */
    public String getUser() {
        return user;
    }

    /**
     * @param user
     *  the user to set
     */
    public void setUser(String user) {
        this.user = user;
    }
}
